#include "array.h"

#include "../xkit.h"

ArrayHeader *ArrayInit(losu_vm_t vm, size_t size) {
    ArrayHeader *out = __xkit_malloc(sizeof(ArrayHeader));
    out->ref = RefInit(vm);
    out->length = size;
    out->value = __xkit_malloc(sizeof(losu_object) * size);
    if (losu_object_type_false == 0) {
        memset(out->value, 0, sizeof(losu_object) * size);
    } else {
        losu_object ofalse = obj_newfalse(vm);
        for (size_t i = 0; i < size; i ++) {
            out->value[i] = ofalse;
        }
    }
    return out;
}

void ArrayFree(losu_vm_t vm, ArrayHeader *h) {
    RefFree(vm, h->ref);
    __xkit_free(h->value);
    h->ref = NULL;
    h->length = 0;
    h->value = NULL;
    __xkit_free(h);
}

void ArraySet(losu_vm_t vm, ArrayHeader *h, size_t index, losu_object_t o) {
    if (index >= h->length) {
        __error_OutOfIndex(vm);
        return ;
    }
    RefIncrease(vm, h->ref, o, 1);
    RefDecrease(vm, h->ref, h->value + index, 1);
    h->value[index] = *o;
}

void ArrayFill(losu_vm_t vm, ArrayHeader *h, losu_object_t o) {
    for (size_t i = 0; i < h->length; i ++) {
        ArraySet(vm, h, i, o);
    }
}

bool ArrayGet(losu_vm_t vm, ArrayHeader *h, size_t index, losu_object_t target) {
    if (index >= h->length) {
        __error_OutOfIndex(vm);
        return false;
    }
    *target = h->value[index];
    return true;
}
